package com.pdg.mcplugin.tsa;

import java.util.HashSet;
import java.util.logging.Logger;

import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.Sign;
import org.bukkit.entity.Player;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerListener;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.permissions.Permission;
import com.iCo6.iConomy;
import com.iCo6.system.Account;
import com.iCo6.system.Accounts;

public class TSAPlayerListener extends PlayerListener{

	//plugin property
	private TSA plugin;
	public TSA getPlugin(){
		return plugin;
	}
	
	//logger property
	public Logger getLogger(){
		return getPlugin().getLogger();
	}
	
	//constructor
	public TSAPlayerListener(TSA thePlugin){
		plugin = thePlugin;
	}
	
	//grab departure use permission
	private boolean hasDepartureUse(Player player){
		//create permission if it doesn't already exist
		if(getPlugin().getPluginManager().getPermission(Constants.permissionDepartureSignPassenger)==null){
			getPlugin().getPluginManager().addPermission(new Permission(Constants.permissionDepartureSignPassenger, Constants.permissionDefaultDeparturesSignPassenger));
		}
		return player.hasPermission(Constants.permissionDepartureSignPassenger);
	}
	
	//grab departure marshal permission
	private boolean hasDepartureMarshal(Player player){
		//create permission if it doesn't exist
		if(getPlugin().getPluginManager().getPermission(Constants.permissionDepartureSignMarshal)==null){
			getPlugin().getPluginManager().addPermission(new Permission(Constants.permissionDepartureSignMarshal, Constants.permissionDefaultDepartureSignMarshal));
		}
		return player.hasPermission(Constants.permissionDepartureSignMarshal);
	}
	
	//check for contraband
	private boolean hasContraband(Player player){
		PlayerInventory inventory = player.getInventory();
		HashSet<Material> contraband = getPlugin().getDataProvider().listContraband();
		for(Material material:contraband){
			if(inventory.contains(material.getId())){
				return true;
			}
		}
		return false;
	}
	
	public void onPlayerInteract(PlayerInteractEvent event){
		//check for a right click
		if(event.getAction() == Action.RIGHT_CLICK_BLOCK){
			
			//check for a sign
			Block clickedBlock = event.getClickedBlock();
			if(clickedBlock.getType()==Material.SIGN_POST || clickedBlock.getType()==Material.WALL_SIGN){
				if(clickedBlock.getState() instanceof Sign){
					
					//grab sign
					Sign clickedSign = (Sign)clickedBlock.getState();
					
					//check that this is a departure point
					if(clickedSign.getLine(Constants.signLineTsa).equalsIgnoreCase(Constants.signStartLine)&&clickedSign.getLine(Constants.signLineType).equalsIgnoreCase(Constants.signDepartureLine)){
						
						//cancel event so that we aren't dropping blocks next to the sign
						event.setCancelled(true);
						
						//is the player allowed to use departure points?
						if(!hasDepartureUse(event.getPlayer())){
							//nope!
							event.getPlayer().sendMessage(Constants.errorDeparturePointUse);
							return;
						}
						
						//is the player carrying contraband?
						if(hasContraband(event.getPlayer())){
							//is the player not a "marshal"?
							if(!hasDepartureMarshal(event.getPlayer())){
								//cannot travel
								event.getPlayer().sendMessage(Constants.errorDeparturePointUseContraband);
								return;
							}
						}
						
						//determine cost, default to zero
						Double cost = Constants.costZero;
						try{
							cost = Double.valueOf(clickedSign.getLine(Constants.signLineCost));
						}catch(Exception e){
							//bad cost line
							event.getPlayer().sendMessage(Constants.errorDeparturePointUseCost);
							e.printStackTrace();
							return;
						}
						
						//determine location of arrival point
						Location location = getPlugin().getDataProvider().retrieveArrival(clickedSign.getLine(Constants.signLineArrivalPoint));
						
						//if location exists and cost greater than zero
						if(location!=null && cost>Constants.costZero){
							
							//grab economy
							iConomy economy = getPlugin().getServerListener().getEconomy();
							if(economy==null){
								//economy not found
								event.getPlayer().sendMessage(Constants.errorDeparturePointUseNoEconomy);
								return;
							}
							
							//grab players account
							Accounts accounts = new Accounts();
							Account account = accounts.get(event.getPlayer().getName());

							//check for enough money
							if(account.getHoldings().hasEnough(cost)){
								
								//take the money
								account.getHoldings().subtract(cost);
								event.getPlayer().sendMessage(String.format(Constants.messageDeparturePointUsePaid,cost));
							}else{
								
								//not enough money
								event.getPlayer().sendMessage(String.format(Constants.errorDeparturePointUseNotEnoughMoney,cost));
								return;
							}
						}
						//if the location exists...
						if(location!=null){
							//teleport player
							event.getPlayer().teleport(location);
							event.getPlayer().sendMessage(String.format(Constants.messageDeparturePointUseArrive,clickedSign.getLine(Constants.signLineArrivalPoint)));
						}else{
							//location not found
							event.getPlayer().sendMessage(String.format(Constants.errorDeparturePointUseArrivalPointNotFound,clickedSign.getLine(Constants.signLineArrivalPoint)));
						}
					}
				}
			}
		}
	}
}
